/**
 * 深度proxy代理
 * @author tsdy 
 */

let ArrayMathod: Array<string> = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse']
// let arr = []
/**
 * 
 * @param path 对象路径
 * @example
 * obj['name'] 相当于 "obj.name"
 * obj.array[1] 相当于 "obj.array.1" 遇到数组的属性发生变化（obj.array[1] = 1）统一更新数组obj.array
 */
function deepProxy(obj: any, get: Function, set: Function, path: string) {
  if (typeof obj === "object") {
    for (let key in obj) {
      if (typeof obj[key] === "object") {
        obj[key] = deepProxy(obj[key], get, set, path + key + ".");
      }
      /**
       * 数组要特殊处理
       */
      if (Array.isArray(obj[key])) {
        let arrayMethod = Object.create(Array.prototype)
        ArrayMathod.forEach(item => {
          Object.defineProperty(arrayMethod, item, {
            enumerable: true,
            configurable: true,
            value: function () {
              let args: any = [...arguments];
              let arr = [...obj[key]];
              
              arr[<any>item].apply(arr, args);
              obj[key] = deepProxy(arr, get, set, path + key + ".");
              /**
               * 这里会导致，调用shift时，set函数中出现.__proto__键名
               */
              obj[key].__proto__ = arrayMethod;
            }
          })
        })
        obj[key].__proto__ = arrayMethod;
      }
    }
  }

  return new Proxy(obj, {
    get(target, key: string, receiver) {
      // 排除数组方法的回调
      if ((typeof target[key] != "object" || Array.isArray(target[key])) && typeof target[key] != 'function' && typeof key != 'symbol') {
        //排除数组修改length回调
        if (!(Array.isArray(target) && key == 'length')) {
            get(path + key);
        }
      }
      return target[key];
    },
    set(target, key: string, value: any, receiver: object) {
      // console.log(target)
      // console.log(value)
      if (typeof value === "object" && !Array.isArray(value)) {
        value = deepProxy(value, get, set, path + key + ".");
      }
      // } else if (Array.isArray(value)) {
      //   console.log('sada',target)
      // }
      if (value == target[key]) {
        return true;
      }
      let cbType = target[key] == undefined ? "create" : "modify";
      //排除数组修改length回调
      if (!(Array.isArray(target) && key === "length")) {
        // if (isArrayMethod && Array.isArray(target)) {
        //   let arr = [...target];
        //   // console.log(arguments);
        // }
      }
      /**
       * 传入的set函数中的计算属性，依赖于（data）proxy中的值
       * 所以要放在Reflect.set 下面
       */
      Reflect.set(target, key, value);
      set(path + key, value);
      return true;
    }
    
  });
}

export { deepProxy };
